//Integration data
// 2009-08-15 dgl created

#ifndef _UN_COREINT
#define _UN_COREINT

#define _CRT_SECURE_NO_WARNINGS

#define MPI_ON
#ifndef MPI_ON
//  #define OMP_ON
  #define __DGL_DEBUG
#endif

#define C_SUCCESS 0
#define C_FAILURE 1
#define C_OVERFLOW 2
#define C_UNDERFLOW 3
#define C_STEPTOOSMALL 4
#define C_TOOMANYSTEPS 5

#define TINY_DOUBLE 1e-300
#define HUGE_DOUBLE 1e100

#define MAX_PARAMS_NUM 10

#include <stdio.h>
typedef enum _intmethod 
 {
   IM_EULER,
   IM_RK4,
   IM_RK4VS,
   IM_DOPRI54,
   IM_RADAUIIA
 } intmethod;


typedef int (* TOdeFunc)(double, double*, double*, double*, int, int, int);
						//time, state, params, result, firstn, lastn, dimension
typedef int (* TDdeFunc)(double, double**, double*, double*, int, int*, int);
						//time, stateS, params, result, dimension, Area, AreaCount

typedef struct ddeparams
{
	double tp1start;
	double tp1finish;
	double tp1step;
	double tp2start;
	double tp2finish;
	double tp2step;

	double traceparam1value;
	double traceparam2value;

	int sysparamcount;
	double sysparams[MAX_PARAMS_NUM];

	int dim;
	double step;
	double atol;
	double rtol;
	
	double delstart;
	double delfinish;
	double delstep;
	int wavek;
	int loadperiods;
	int savesolution;
	int unitstocomp;

} TddeParams;


typedef struct odesys
{
  int dim;            //dimension
  TOdeFunc func;      //right part of the ODE
  double* state;      //initial conditon
  double* params;     //parameters
  double* state2;     //variable do decrease mallocs
  double time;        //current system time    
} TOdeSys;


typedef struct dmemnode
{
  struct dmemnode*  next;
  double t;
  double* v;
} TDMemNode;

typedef struct dmemory
{
  int length;
  TDMemNode *retard;        
} TDdeMemory;

typedef struct ddesys
{
  int dim;            //dimension
  TDdeFunc func;      //right part of the ODE
  double* state;      //initial conditon
  double** args;     //pointers to vectors containing state and delayed state 
  double* state2;     //variable do decrease mallocs
  double* params;     //parameters
  double time;        //current system time     
  int *Area;          //array of bounds 2*AreaCount
  int AreaCount;      //
  TDdeMemory mem;
} TDdeSys;


typedef struct
{
  double** stor;
  int     state_ref;
  int      dim;    //dimention of every vector in stor
  int      num;    //number of vectors in stor
  double   step;
  double   time;
  int      numthreads;
  int      threadnum;
  int      nfirst; //first and last equation in section
  int      nlast;
  double   atol; //absolute tolerance
  double   rtol; //relative tolerance
  int      rejected; //rejected steps
  int      accepted; //accepted steps
#ifdef __DGL_DEBUG
    FILE*    log;
#endif
  
} TMethodData;

typedef int (* TOdeMethod)(TOdeSys*);


int OdeIntegrateNstep(TOdeMethod,TOdeSys*,int);
int OdeSysInit(TOdeSys* system,int,TOdeFunc,double*,double,double*);
int OdeSysFree(TOdeSys*);

int DdeSysInitwArea(TDdeSys*, int, TDdeFunc, 
			   double*, double, double*, double, double, int*, int); //this one is for custom area
int DdeSysInit(TDdeSys*, int, TDdeFunc, 
			   double*, double, double*, double, double);  //this one is for general area (line, square, etc.)
int DdeSysFree(TDdeSys*);
int DdeMemInit(TDdeMemory*, double, double, int);
int DdeHistoryFillwConstant(TDdeMemory*, double*, int, double);
int DdeMemFree(TDdeMemory*);

int MethodDataInit(TMethodData*,int,intmethod,double,double,double);
int MethodDataFree(TMethodData*);

#endif
